package cn.tedu.csmall.product.service.impl;

import cn.tedu.csmall.commons.pojo.vo.PageData;
import cn.tedu.csmall.product.cache.AlbumCacheRepository;
import cn.tedu.csmall.product.ex.ServiceException;
import cn.tedu.csmall.product.mapper.AlbumMapper;
import cn.tedu.csmall.product.mapper.PictureMapper;
import cn.tedu.csmall.product.mapper.SKUMapper;
import cn.tedu.csmall.product.mapper.SPUMapper;
import cn.tedu.csmall.product.pojo.entity.Album;
import cn.tedu.csmall.product.pojo.entity.Picture;
import cn.tedu.csmall.product.pojo.entity.SKU;
import cn.tedu.csmall.product.pojo.entity.SPU;
import cn.tedu.csmall.product.pojo.param.AlbumAddNewParam;
import cn.tedu.csmall.product.pojo.param.AlbumUpdateInfoParam;
import cn.tedu.csmall.product.pojo.vo.AlbumListItemVO;
import cn.tedu.csmall.product.pojo.vo.AlbumStandardVO;
import cn.tedu.csmall.product.service.AlbumService;
import cn.tedu.csmall.commons.util.PageInfoToPageDataConverter;
import cn.tedu.csmall.product.web.ServiceCode;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Optional;

@Service
@Slf4j
public class AlbumServiceImpl implements AlbumService {

    // 需要加上@Service注解，否则自动装配无效
    @Autowired
    private AlbumMapper albumMapper;
    @Autowired
    private PictureMapper pictureMapper;
    @Autowired
    private SPUMapper spuMapper;
    @Autowired
    private SKUMapper skuMapper;

    @Override
    public void addNew(AlbumAddNewParam albumAddNewParam) {
        // 检测相册名称是否被占用，如果占用，则抛出异常
        QueryWrapper<Album> queryWrapper = new QueryWrapper<>();
        // wrapper中匹配数据库中“name”字段=参数中的值
        queryWrapper.eq("name",albumAddNewParam.getName());
        int countByName = albumMapper.selectCount(queryWrapper);
        if (countByName > 0) {
            String message = "【ServiceException:添加相册失败，相册名称已经被占用！】";
            log.debug("【log.info:添加相册失败，相册名称已经被占用！】");
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 将相册数据写入数据库中
        Album album = new Album();
        BeanUtils.copyProperties(albumAddNewParam,album);
        album.setGmtCreate(LocalDateTime.now());
        album.setGmtModified(LocalDateTime.now());
        int rows = albumMapper.insert(album);

        if (rows != 1) {
            String msg = "添加相册失败，服务器忙，请稍后再试！";
            log.warn(msg);
            // 抛出异常就能回滚
            throw new ServiceException(ServiceCode.ERR_INSERT, msg);
        }
    }

    @Override
    public void deleteById(Long albumId) {
        QueryWrapper<Album> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",albumId);
        int countById = albumMapper.selectCount(queryWrapper);
        if (countById > 0) {

            // 检查是否有图片关联到了此相册，如果有，则不能删除该相册
            QueryWrapper<Picture> pictureQueryWrapper = new QueryWrapper<>();
            pictureQueryWrapper.eq("album_id",albumId);
            int countByAlbumId1 = pictureMapper.selectCount(pictureQueryWrapper);
            if (countByAlbumId1 > 0) {
                throw new ServiceException(ServiceCode.ERR_CONFLICT, "该相册有附属图片，请转移后删除！");
            }

            // 检查是否有SPU关联到了此相册，如果有，则不能删除该相册
            QueryWrapper<SPU> spuQueryWrapper = new QueryWrapper<>();
            spuQueryWrapper.eq("album_id",albumId);
            int countByAlbumId2 = spuMapper.selectCount(spuQueryWrapper);
            if (countByAlbumId2 > 0) {
                throw new ServiceException(ServiceCode.ERR_CONFLICT, "该相册有附属SPU，请转移后删除！");
            }

            // 检查是否有SKU关联到了此相册，如果有，则不能删除该相册
            QueryWrapper<SKU> skuQueryWrapper = new QueryWrapper<>();
            skuQueryWrapper.eq("album_id",albumId);
            int countByAlbumId3 = skuMapper.selectCount(skuQueryWrapper);
            if (countByAlbumId3 > 0) {
                throw new ServiceException(ServiceCode.ERR_CONFLICT, "该相册有附属SKU，请转移后删除！");
            }

            // 不会抛出异常（即该相册没有附属的东西），则允许删除
            int rows = albumMapper.deleteById(albumId);
            if (rows != 1) {
                String msg = "删除相册失败，服务器忙，请稍后再试！";
                log.warn(msg);
                // 抛出异常就能回滚
                throw new ServiceException(ServiceCode.ERR_DELETE, msg);
            }
            return;
        }
        String message = "【ServiceException:删除失败，没有该相册ID！】";
        log.debug("【log.info:删除失败，没有该相册ID！！】");
        throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
    }

    @Override
    public void updateInfoById(Long id, AlbumUpdateInfoParam albumUpdateInfoParam) {
        // 修改前判断数据是否存在
        QueryWrapper<Album> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",id);
        int countById = albumMapper.selectCount(queryWrapper);
        if (countById == 0) {
            String message = "【ServiceException:修改相册失败，没有该相册！】";
            log.debug("【log.info:修改相册失败，没有该相册！】");
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }

        // 修改前判断相册名称是否被其他相册占用，如果占用则抛出异常
        QueryWrapper<Album> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("name",albumUpdateInfoParam.getName())// name == name
                .ne("id",id);// id != id
        int countByName = albumMapper.selectCount(queryWrapper2);
        if (countByName > 0) {
            String message = "【ServiceException:修改相册失败，名称被占用！】";
            log.debug("【log.info:修改相册失败，名称被占用！】");
            throw new ServiceException(ServiceCode.ERR_CONFLICT, message);
        }

        // 执行修改
        log.debug("开始处理【修改相册详情】的业务，参数：{}",albumUpdateInfoParam);
/*
    mybatis plus 的 updateById 会对null值不做数据库更新，若非要设置null值，则可以
*/

//        Album album = Optional.ofNullable(albumMapper.selectById(id)).orElseThrow(RuntimeException::new);
//        LambdaUpdateWrapper<Album> updateWrapper = new LambdaUpdateWrapper<>();
//        updateWrapper.set(Album::getName, albumUpdateInfoParam.getName());
//        updateWrapper.set(Album::getSort, albumUpdateInfoParam.getSort());
//        updateWrapper.set(Album::getDescription, albumUpdateInfoParam.getDescription());
//        updateWrapper.set(Album::getGmtModified, LocalDateTime.now());
//        updateWrapper.set(Album::getGmtCreate, null);
//        updateWrapper.eq(Album::getId, id);
//        int rows = albumMapper.update(album, updateWrapper);
        Album album = new Album();
        BeanUtils.copyProperties(albumUpdateInfoParam,album);
        album.setId(id);
        album.setGmtModified(LocalDateTime.now());
        int rows = albumMapper.updateById(album);
        if (rows != 1) {
            String msg = "修改相册详情失败，服务器忙，请稍后再试！";
            log.warn(msg);
            // 抛出异常就能回滚
            throw new ServiceException(ServiceCode.ERR_UPDATE, msg);
        }
        log.debug("新的相册数据更新到数据库完成！");
    }

    @Override
    public PageData<AlbumListItemVO> list(Integer pageNum) {
        Integer pageSize = 5;
        return list(pageNum, pageSize);
    }

    @Override
    public PageData<AlbumListItemVO> list(Integer pageNum, Integer pageSize) {
        log.debug("开始处理【分页查询相册列表】的业务，页码：{}，每页记录数：{}", pageNum, pageSize);
        // PageHelper框架的用法，这两句需要一起
        PageHelper.startPage(pageNum,pageSize);
        List<AlbumListItemVO> list = albumMapper.list();
        // 基于查询结果创建PageInfo对象，此对象中包括大量分页查询时的参数
        PageInfo<AlbumListItemVO> pageInfo = new PageInfo<>(list);
        // pageInfo --> pageData
        return PageInfoToPageDataConverter.convert(pageInfo);
    }

    @Autowired
    private AlbumCacheRepository repository;

    @Override
    public AlbumStandardVO getStandardById(Long id) {

        log.debug("开始处理【根据ID查询相册】的业务，ID值为：{}", id);
        AlbumStandardVO result = repository.getStandardById(id);
        if (result == null) {
            String message = "【根据ID查询相册】失败，类别数据不存在！";
            log.debug(message);
            throw new ServiceException(ServiceCode.ERR_NOT_FOUND, message);
        }
        return result;
    }

}
